package com.gientech.group9.service;

import com.gientech.group9.model.ApplyRecord;
import com.gientech.group9.model.AuditLog;
import com.gientech.group9.repository.ApplyRecordRepository;
import com.gientech.group9.repository.AuditLogRepository;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;

@Service
public class ApplyRecordService {
    protected final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    RuntimeService runtimeService;
    @Autowired
    RepositoryService repositoryService;
    @Autowired
    TaskService taskService;
    @Resource
    private ApplyRecordRepository applyRecordRepository;
    @Resource
    private AuditLogRepository auditLogRepository;

    public List<ApplyRecord> getApplyRecords(ApplyRecord row, Sort sort) {

        return applyRecordRepository.findAll(Example.of(row != null ? row : new ApplyRecord()), sort);
    }

    public void examineAndApprove(String processInstanceId, Boolean approved) {

        logger.info("processInstanceId:");
        logger.info(processInstanceId);
        // 客户申请
        HashMap<String, Object> map = new HashMap<>();
        map.put("approved", approved);
        map.put("approved1", approved);
        map.put("approved2", approved);
        map.put("assignee6", "assignee6");

        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();
        taskService.complete(task.getId(), map);
    }

    public ApplyRecord save(ApplyRecord applyRecord) throws RuntimeException {
        HashMap<String, Object> map = new HashMap<>();
        map.put("assignee0", "assignee0");
        map.put("assignee1", "assignee1");
        map.put("assignee2", "assignee2");
        map.put("assignee3", "assignee3");
        map.put("assignee4", "assignee4");
        map.put("assignee5", "assignee5");
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("个人信用贷款", map);
        System.out.println("-----------processInstance.getId()---------");
        System.out.println(processInstance.getId());
        // processInstance.getId() 需要保存到表里
        applyRecord.setProcessInstanceId(processInstance.getId());

        ApplyRecord save = applyRecordRepository.save(applyRecord);

        // 客户申请
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
        taskService.complete(task.getId());
        // 业务处理自动执行
        return save;
    }

    @Transactional
    public AuditLog audit(AuditLog auditLog, Boolean approved) throws RuntimeException {
        Integer applyId = auditLog.getApplyId();
        Optional<ApplyRecord> byId = applyRecordRepository.findById(applyId);
        if (byId.isPresent()) {

            ApplyRecord applyRecord = byId.get();
            Integer oldStatus = applyRecord.getStatus();
            Integer newStatus = auditLog.getStatus();
            if ((newStatus > 0 && oldStatus >= 0 && newStatus > oldStatus) || newStatus < 0) {
                applyRecord.setStatus(auditLog.getStatus());
                applyRecord.setAuditDate(new Date());
                ApplyRecord save = applyRecordRepository.save(applyRecord);
                BeanUtils.copyProperties(applyRecord, auditLog);
                AuditLog save2 = auditLogRepository.save(auditLog);

                logger.info("apply record == null:", applyRecord == null ? "true" : "false");
                logger.info("audit apply record:", applyRecord.getApplyId());
                if (StringUtils.isNotEmpty(applyRecord.getProcessInstanceId())) {
                    examineAndApprove(applyRecord.getProcessInstanceId(), approved);
                }
                return save2;
            } else {
                throw new RuntimeException("非法操作");
            }

        } else {
            throw new RuntimeException("没找到记录");
        }

    }

    public Optional<ApplyRecord> getApplyRecordById(Integer applyId) {
        return applyRecordRepository.findById(applyId);
    }
}
